package com.dzz.sjgl.service.impl;

import com.dzz.sjgl.entity.PaperInfo;
import com.dzz.sjgl.entity.PaperWord;
import com.dzz.sjgl.entity.SentenceInfo;
import com.dzz.sjgl.entity.WordInfo;
import com.dzz.sjgl.jpa.PaperRepository;
import com.dzz.sjgl.jpa.PaperWordRepository;
import com.dzz.sjgl.jpa.SentenceRepository;
import com.dzz.sjgl.jpa.WordRepository;
import com.dzz.sjgl.service.IPaperService;
import com.dzz.sjgl.utils.SpliteTextInSentence;
import com.dzz.sjgl.utils.Word2String;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author KRIC
 * @ClassName UserServiceImpl
 * @Date: 2018-8-1 17:25
 * @Description:
 */
@Service
@PropertySource("classpath:config.properties")
public class PaperServiceImpl implements IPaperService {
    @Value("${file.path}")
    private String path;
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private final PaperRepository paperRepository;
    private final SentenceRepository sentenceRepository;
    private final WordRepository wordRepository;
    private final PaperWordRepository paperWordRepository;

    @Autowired
    public PaperServiceImpl(PaperRepository paperRepository, SentenceRepository sentenceRepository, WordRepository wordRepository, PaperWordRepository paperWordRepository) {
        this.paperRepository = paperRepository;
        this.sentenceRepository = sentenceRepository;
        this.wordRepository = wordRepository;
        this.paperWordRepository = paperWordRepository;
    }

    /**
     * 文件是否已经存在
     */
    @Override
    public boolean isExist(String name, String subjects) {
        long count = paperRepository.count((Specification<PaperInfo>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (!StringUtils.isEmpty(name)) {
                predicateList.add(criteriaBuilder.equal(root.get("name").as(String.class), name.trim()));
            }
            if (!StringUtils.isEmpty(subjects)) {
                predicateList.add(criteriaBuilder.equal(root.get("subjects").as(String.class), subjects.trim()));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
        });
        return count > 0;
    }

    /**
     * 保存试卷信息
     */
    @Override
    public PaperInfo saveAndFlush(PaperInfo paperInfo) {
        return paperRepository.saveAndFlush(paperInfo);
    }

    /**
     * word文档解析
     */
    @Override
    public void parsingWord(int paperId) {
        PaperInfo paperInfo = getOne(paperId);
        String wordPath = paperInfo.getWordPath();
        if (StringUtils.isEmpty(wordPath)) {
            logger.error("word没有路径！");
            paperInfo.setStatus("9");
            saveAndFlush(paperInfo);
            return;
        }
        String text = Word2String.getText(path + wordPath);
        if (StringUtils.isEmpty(text)) {
            logger.error("word读取异常！");
            paperInfo.setStatus("9");
            saveAndFlush(paperInfo);
            return;
        }
//       提取单词  统计词频
        String pattern = "[a-zA-Z]+";
        Map<String, Integer> map = new TreeMap<>();
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);
        while (m.find()) {
            String s = m.group();
            if (StringUtils.isEmpty(s)) {
                continue;
            }
            s = s.toLowerCase();
            Integer times = map.get(s);
            if (times == null) {
                map.put(s, 1);
            } else {
                map.put(s, ++times);
            }
        }
//        单词入库
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String word = entry.getKey();
            int count = entry.getValue();
            WordInfo wordInfo = wordRepository.getByWord(word);
            if (wordInfo == null) {
                continue;
            }
            PaperWord paperWord = new PaperWord();
            paperWord.setPaperId(paperId);
            paperWord.setWordId(wordInfo.getId());
            paperWord.setWordCount(count);
            paperWordRepository.save(paperWord);
        }

//        提取句子
        text = text.replaceAll("[A-G][.]", "\r\n ❤. ");
        text = SpliteTextInSentence.splitfuhao(text);
        Set<String> sl = new HashSet<>(SpliteTextInSentence.testChunkSentences(text));
        if (sl.isEmpty()) {
            logger.warn("没有识别到句子");
        }
        Set<String> sentences = new HashSet<>();
        for (String row : sl) {
            row = row.replaceAll("[0-9]{1,2}[.]", " ");
            row = row.replaceAll("　", "");
            row = row.replaceAll("●", "");
            row = row.replaceAll("\\s{1,}", " ");
            row = row.replaceAll(" [.]", ".");
            row = row.replaceAll("[.]+|[?][.]", ".");
            row = row.replace("例:", "");
            String regEx = "[\\u4e00-\\u9fa5]";
            String term = row.replaceAll(regEx, "aa");
            int count = term.length() - row.length();
            if (count > 2 || (row.indexOf("❤.") != row.lastIndexOf("❤."))) {
                continue;
            }
            row = row.replace("❤.", "");
            if (row.length() > 10 && row.length() < 600) {
                sentences.add(row.trim());
            }
        }
        for (String sentence : sentences) {
            SentenceInfo sentenceInfo = new SentenceInfo();
            sentenceInfo.setPaperId(paperId);
            sentenceInfo.setSentence(sentence);
            sentenceRepository.save(sentenceInfo);
        }
//        删除句子脏数据
        int count = sentenceRepository.delDirtyData();
        logger.info("删除了" + count + "条脏句子");
        paperInfo.setStatus("1");
        saveAndFlush(paperInfo);
    }

    /**
     * 通过id查询试卷信息
     */
    @Override
    public PaperInfo getOne(int paperId) {
        return paperRepository.getOne(paperId);
    }


    /**
     * 分页
     */
    @Override
    public Page<PaperInfo> findAllByQuery(int pageNum, int pageSize, String name, String subjects, String province, String exam, Integer minYear, Integer maxYear) {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return paperRepository.findAll((Specification<PaperInfo>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (!StringUtils.isEmpty(name)) {
                predicateList.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + name.trim() + "%"));
            }
            if (!StringUtils.isEmpty(subjects)) {
                predicateList.add(criteriaBuilder.equal(root.get("subjects").as(String.class), subjects.trim()));
            }
            if (!StringUtils.isEmpty(province)) {
                predicateList.add(criteriaBuilder.equal(root.get("province").as(String.class), province.trim()));
            }
            if (!StringUtils.isEmpty(exam)) {
                predicateList.add(criteriaBuilder.equal(root.get("exam").as(String.class), exam.trim()));
            }
            if (minYear != null) {
                predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("year").as(Integer.class), minYear));
            }
            if (maxYear != null) {
                predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("year").as(Integer.class), maxYear));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
        }, pageable);
    }

    /**
     * 解析未处理的试卷
     */
    @Override
    public void parsingWordsByStatus(String status) {
        List<PaperInfo> paperInfos = getListByStatus(status);
        for (PaperInfo paperInfo : paperInfos) {
            parsingWord(paperInfo.getId());
        }
    }

    /**
     * 根据状态获取试卷信息
     */
    @Override
    public List<PaperInfo> getListByStatus(String status) {
        return paperRepository.findAll((Specification<PaperInfo>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (!StringUtils.isEmpty(status)) {
                predicateList.add(criteriaBuilder.equal(root.get("status").as(String.class), status.trim()));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
        });
    }

    /**
     * 删除试卷,ids传字符串，多个用','隔开
     */
    @Override
    public int delPapers(String ids) {
        String[] idsArr = ids.split(",");
        List<Integer> idList = new ArrayList<>();
        for (String s : idsArr) {
            idList.add(Integer.valueOf(s));
        }
        int total = paperRepository.delPapers(idList);
        logger.error("删除了" + total + "条试卷");
        paperWordRepository.del(idList);
        sentenceRepository.del(idList);
        return total;
    }


}
